/**
 * Generali Solutions d'assurances - Tous droits reserves &copy; 2007 - 2010
 */
package fr.generali.accueilclient.editique.courrier.services.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Transformer;
import org.springframework.stereotype.Component;

import fr.generali.accueilclient.editique.om.ICleRecherche;
import fr.generali.accueilclient.editique.om.ICriteresCleRecherche;
import fr.generali.accueilclient.editique.om.ICriteresCourrierParCle;
import fr.generali.accueilclient.editique.om.ICriteresFiltreInfoCompDefinition;
import fr.generali.accueilclient.editique.om.IFiltreInfoCompDefinition;
import fr.generali.accueilclient.editique.om.IInfoCompCourrier;
import fr.generali.accueilclient.editique.om.IListRechercheCourrierParCle;
import fr.generali.accueilclient.editique.om.IRechercheCourrierParCle;
import fr.generali.accueilclient.editique.om.impl.CleRecherche;
import fr.generali.accueilclient.editique.om.impl.FiltreInfoCompDefinition;
import fr.generali.accueilclient.editique.om.impl.InfoCompCourrier;
import fr.generali.accueilclient.editique.om.impl.ListRechercheCourrierParCle;
import fr.generali.accueilclient.editique.om.impl.RechercheCourrierParCle;
import fr.generali.accueilclient.utils.spel.mapping.Mapper;
import fr.generali.accueilclient.utils.spel.mapping.support.MapperBuilder;
import fr.generali.accueilclient.utils.spel.mapping.support.MapperFactory;
import fr.generali.editique.page.ws.clerecherche.ArrayOfString;
import fr.generali.editique.page.ws.clerecherche.dto.ArrayOfRepCleRechercheDto;
import fr.generali.editique.page.ws.clerecherche.dto.ArrayOfRepCourrierParCleRechercheDto;
import fr.generali.editique.page.ws.clerecherche.dto.ArrayOfRepFiltreInfoCompDefinitionDto;
import fr.generali.editique.page.ws.clerecherche.dto.ArrayOfRepInfoCompCourrierDto;
import fr.generali.editique.page.ws.clerecherche.dto.ArrayOfReqCleRechercheDto;
import fr.generali.editique.page.ws.clerecherche.dto.ArrayOfReqFiltreInfoCompDefinitionDto;
import fr.generali.editique.page.ws.clerecherche.dto.RepCleRechercheDto;
import fr.generali.editique.page.ws.clerecherche.dto.RepCourrierParCleRechercheDto;
import fr.generali.editique.page.ws.clerecherche.dto.RepFiltreInfoCompDefinitionDto;
import fr.generali.editique.page.ws.clerecherche.dto.RepInfoCompCourrierDto;
import fr.generali.editique.page.ws.clerecherche.dto.RepRechercheCourrierParCleDto;
import fr.generali.editique.page.ws.clerecherche.dto.ReqCleRechercheDto;
import fr.generali.editique.page.ws.clerecherche.dto.ReqCourrierParCleDto;
import fr.generali.editique.page.ws.clerecherche.dto.ReqFiltreInfoCompDefinitionDto;

/**
 * The Class RechercheCourrierParCleMapper.
 * 
 * @author Holmes Kelly
 */
@Component("rechercheCourrierParCleMapper")
public class RechercheCourrierParCleMapper {

    /**
     * Mapper i criteres courrier par cle to req courrier par cle dto.
     * 
     * @param criteresCourrierParCle the criteres courrier par cle
     * @return the req courrier par cle dto
     */
    public ReqCourrierParCleDto mapperICriteresCourrierParCleToReqCourrierParCleDto(
                    ICriteresCourrierParCle criteresCourrierParCle) {

        ReqCourrierParCleDto reqCourrierParCleDto = null;

        if (criteresCourrierParCle != null) {

            reqCourrierParCleDto = new ReqCourrierParCleDto();

            MapperBuilder<ICriteresCourrierParCle, ReqCourrierParCleDto> mapperBuilder =
                            MapperFactory.mapperBuilder(ICriteresCourrierParCle.class, ReqCourrierParCleDto.class);

            mapperBuilder.addNestedMapper(mapListICriteresCleRechercheToArrayOfReqCleRechercheDto())
                            .addNestedMapper(
                                            mapICriteresFiltreInfoCompDefinitionToArrayOfReqFiltreInfoCompDefinitionDto())
                            .getMapper().map(criteresCourrierParCle, reqCourrierParCleDto);

        }

        return reqCourrierParCleDto;

    }

    /**
     * Mapper rep recherche courrier par cle dto to i list recherche courrier
     * par cle.
     * 
     * @param repRechercheCourrierParCleDto the rep recherche courrier par cle
     *            dto
     * @return the i list recherche courrier par cle
     */
    public IListRechercheCourrierParCle mapperRepRechercheCourrierParCleDtoToIListRechercheCourrierParCle(
                    RepRechercheCourrierParCleDto repRechercheCourrierParCleDto) {

        IListRechercheCourrierParCle listRechercheCourrierParCle = null;

        if (repRechercheCourrierParCleDto != null) {

            listRechercheCourrierParCle = new ListRechercheCourrierParCle();

            List<IRechercheCourrierParCle> listeRechercheCourrierParCles = new ArrayList<IRechercheCourrierParCle>(0);

            listRechercheCourrierParCle
                            .setReponseCourrierDto(mapArrayOfRepCourrierParCleRechercheDtoToListIRechercheCourrierParCle()
                                            .map(repRechercheCourrierParCleDto.getReponseCourrierDto(),
                                                            listeRechercheCourrierParCles));

        }

        return listRechercheCourrierParCle;
    }

    /**
     * Map list i criteres cle recherche to array of req cle recherche dto.
     * 
     * @return the mapper
     */
    private Mapper<List<ICriteresCleRecherche>, ArrayOfReqCleRechercheDto> mapListICriteresCleRechercheToArrayOfReqCleRechercheDto() {

        Mapper<List<ICriteresCleRecherche>, ArrayOfReqCleRechercheDto> map =
                        new Mapper<List<ICriteresCleRecherche>, ArrayOfReqCleRechercheDto>() {

                            @Override
                            public ArrayOfReqCleRechercheDto map(List<ICriteresCleRecherche> source,
                                            ArrayOfReqCleRechercheDto target) {

                                if (CollectionUtils.isNotEmpty(source)) {

                                    List<ReqCleRechercheDto> reqCleRechercheDto = new ArrayList<ReqCleRechercheDto>(0);

                                    CollectionUtils.collect(source,
                                                    transformICriteresCleRechercheToReqCleRechercheDto(),
                                                    reqCleRechercheDto);

                                    target.getReqCleRechercheDto().addAll(reqCleRechercheDto);

                                }

                                return target;
                            }
                        };

        return map;
    }

    /**
     * Map i criteres filtre info comp definition to array of req filtre info
     * comp definition dto.
     * 
     * @return the mapper
     */
    private Mapper<List<ICriteresFiltreInfoCompDefinition>, ArrayOfReqFiltreInfoCompDefinitionDto> mapICriteresFiltreInfoCompDefinitionToArrayOfReqFiltreInfoCompDefinitionDto() {

        Mapper<List<ICriteresFiltreInfoCompDefinition>, ArrayOfReqFiltreInfoCompDefinitionDto> map =
                        new Mapper<List<ICriteresFiltreInfoCompDefinition>, ArrayOfReqFiltreInfoCompDefinitionDto>() {

                            @Override
                            public ArrayOfReqFiltreInfoCompDefinitionDto map(
                                            List<ICriteresFiltreInfoCompDefinition> source,
                                            ArrayOfReqFiltreInfoCompDefinitionDto target) {

                                if (CollectionUtils.isNotEmpty(source)) {

                                    List<ReqFiltreInfoCompDefinitionDto> reqFiltreInfoCompDefinitionDto =
                                                    new ArrayList<ReqFiltreInfoCompDefinitionDto>(0);

                                    CollectionUtils.collect(
                                                    source,
                                                    transformICriteresFiltreInfoCompDefinitionToReqFiltreInfoCompDefinitionDto(),
                                                    reqFiltreInfoCompDefinitionDto);

                                    target.getReqFiltreInfoCompDefinitionDto().addAll(reqFiltreInfoCompDefinitionDto);
                                }

                                return target;
                            }
                        };

        return map;
    }

    /**
     * Map array of rep courrier par cle recherche dto to list i recherche
     * courrier par cle.
     * 
     * @return the mapper
     */
    private Mapper<ArrayOfRepCourrierParCleRechercheDto, List<IRechercheCourrierParCle>> mapArrayOfRepCourrierParCleRechercheDtoToListIRechercheCourrierParCle() {

        Mapper<ArrayOfRepCourrierParCleRechercheDto, List<IRechercheCourrierParCle>> map =
                        new Mapper<ArrayOfRepCourrierParCleRechercheDto, List<IRechercheCourrierParCle>>() {

                            @Override
                            public List<IRechercheCourrierParCle> map(ArrayOfRepCourrierParCleRechercheDto source,
                                            List<IRechercheCourrierParCle> target) {

                                if (source != null) {

                                    List<RepCourrierParCleRechercheDto> repCourrierParCleRechercheDto =
                                                    source.getRepCourrierParCleRechercheDto();
                                    target = new ArrayList<IRechercheCourrierParCle>(0);
                                    CollectionUtils.collect(repCourrierParCleRechercheDto,
                                                    transformRepCourrierParCleRechercheDtoToIRechercheCourrierParCle(),
                                                    target);
                                }

                                return target;
                            }
                        };

        return map;
    }

    /**
     * Map array of rep cle recherche dto to list i cle recherche.
     * 
     * @return the mapper
     */
    private Mapper<ArrayOfRepCleRechercheDto, List<ICleRecherche>> mapArrayOfRepCleRechercheDtoToListICleRecherche() {

        Mapper<ArrayOfRepCleRechercheDto, List<ICleRecherche>> map =
                        new Mapper<ArrayOfRepCleRechercheDto, List<ICleRecherche>>() {

                            @Override
                            public List<ICleRecherche> map(ArrayOfRepCleRechercheDto source, List<ICleRecherche> target) {

                                if (source != null) {

                                    List<RepCleRechercheDto> repCleRechercheDto = source.getRepCleRechercheDto();
                                    target = new ArrayList<ICleRecherche>(0);
                                    CollectionUtils.collect(repCleRechercheDto,
                                                    transformRepCleRechercheDtoToICleRecherche(), target);
                                }

                                return target;
                            }
                        };

        return map;
    }

    /**
     * Map array of rep filtre info comp definition dto to list i filtre info
     * comp definition.
     * 
     * @return the mapper
     */
    private Mapper<ArrayOfRepFiltreInfoCompDefinitionDto, List<IFiltreInfoCompDefinition>> mapArrayOfRepFiltreInfoCompDefinitionDtoToListIFiltreInfoCompDefinition() {

        Mapper<ArrayOfRepFiltreInfoCompDefinitionDto, List<IFiltreInfoCompDefinition>> map =
                        new Mapper<ArrayOfRepFiltreInfoCompDefinitionDto, List<IFiltreInfoCompDefinition>>() {

                            @Override
                            public List<IFiltreInfoCompDefinition> map(ArrayOfRepFiltreInfoCompDefinitionDto source,
                                            List<IFiltreInfoCompDefinition> target) {

                                if (source != null) {

                                    List<RepFiltreInfoCompDefinitionDto> repFiltreInfoCompDefinitionDto =
                                                    source.getRepFiltreInfoCompDefinitionDto();
                                    target = new ArrayList<IFiltreInfoCompDefinition>(0);
                                    CollectionUtils.collect(
                                                    repFiltreInfoCompDefinitionDto,
                                                    transformRepFiltreInfoCompDefinitionDtoToIFiltreInfoCompDefinition(),
                                                    target);
                                }

                                return target;
                            }
                        };

        return map;
    }

    /**
     * Map array of rep info comp courrier dto to list i info comp courrier.
     * 
     * @return the mapper
     */
    private Mapper<ArrayOfRepInfoCompCourrierDto, List<IInfoCompCourrier>> mapArrayOfRepInfoCompCourrierDtoToListIInfoCompCourrier() {

        Mapper<ArrayOfRepInfoCompCourrierDto, List<IInfoCompCourrier>> map =
                        new Mapper<ArrayOfRepInfoCompCourrierDto, List<IInfoCompCourrier>>() {

                            @Override
                            public List<IInfoCompCourrier> map(ArrayOfRepInfoCompCourrierDto source,
                                            List<IInfoCompCourrier> target) {

                                if (source != null) {

                                    List<RepInfoCompCourrierDto> repInfoCompCourrierDto =
                                                    source.getRepInfoCompCourrierDto();
                                    target = new ArrayList<IInfoCompCourrier>(0);
                                    CollectionUtils.collect(repInfoCompCourrierDto,
                                                    transformRepInfoCompCourrierDtoToIInfoCompCourrier(), target);
                                }

                                return target;
                            }
                        };

        return map;
    }

    /**
     * Transform i criteres cle recherche to req cle recherche dto.
     * 
     * @return the transformer
     */
    private Transformer transformICriteresCleRechercheToReqCleRechercheDto() {

        Transformer transformer = new Transformer() {

            @Override
            public Object transform(Object input) {

                ICriteresCleRecherche criteresCleRecherche = ICriteresCleRecherche.class.cast(input);

                ReqCleRechercheDto reqCleRechercheDto = new ReqCleRechercheDto();

                reqCleRechercheDto.setTypeCle(criteresCleRecherche.getTypeCle());
                ArrayOfString arrayOfString = new ArrayOfString();
                arrayOfString.getString().addAll(criteresCleRecherche.getValeurCle());
                reqCleRechercheDto.setValeurCle(arrayOfString);

                return reqCleRechercheDto;
            }
        };

        return transformer;
    }

    /**
     * Transform i criteres filtre info comp definition to req filtre info comp
     * definition dto.
     * 
     * @return the transformer
     */
    private Transformer transformICriteresFiltreInfoCompDefinitionToReqFiltreInfoCompDefinitionDto() {

        Transformer transformer = new Transformer() {

            @Override
            public Object transform(Object input) {

                ICriteresFiltreInfoCompDefinition criteresFiltreInfoCompDefinition =
                                ICriteresFiltreInfoCompDefinition.class.cast(input);

                ReqFiltreInfoCompDefinitionDto reqFiltreInfoCompDefinitionDto = new ReqFiltreInfoCompDefinitionDto();

                reqFiltreInfoCompDefinitionDto.setTypeFiltre(criteresFiltreInfoCompDefinition.getTypeFiltre());
                reqFiltreInfoCompDefinitionDto.setValeurFiltre(criteresFiltreInfoCompDefinition.getValeurFiltre());

                return reqFiltreInfoCompDefinitionDto;
            }
        };

        return transformer;
    }

    /**
     * Transform rep courrier par cle recherche dto to i recherche courrier par
     * cle.
     * 
     * @return the transformer
     */
    private Transformer transformRepCourrierParCleRechercheDtoToIRechercheCourrierParCle() {

        Transformer transformer = new Transformer() {

            @Override
            public Object transform(Object input) {

                RepCourrierParCleRechercheDto repCourrierParCleRechercheDto =
                                RepCourrierParCleRechercheDto.class.cast(input);

                IRechercheCourrierParCle rechercheCourrierParCle = new RechercheCourrierParCle();

                rechercheCourrierParCle.setCleRecherche1(repCourrierParCleRechercheDto.getCleRecherche1());
                rechercheCourrierParCle.setCleRecherche2(repCourrierParCleRechercheDto.getCleRecherche2());
                rechercheCourrierParCle.setCleRecherche3(repCourrierParCleRechercheDto.getCleRecherche3());
                rechercheCourrierParCle.setCleRecherche4(repCourrierParCleRechercheDto.getCleRecherche4());
                rechercheCourrierParCle.setCodeSituation(repCourrierParCleRechercheDto.getCodeSituation());
                rechercheCourrierParCle.setCodeUser(repCourrierParCleRechercheDto.getCodeUser());
                rechercheCourrierParCle.setDateCreation(repCourrierParCleRechercheDto.getDateCreation());
                rechercheCourrierParCle.setDefinitionCourrier(repCourrierParCleRechercheDto.getDefinitionCourrier());
                rechercheCourrierParCle.setHeureCreation(repCourrierParCleRechercheDto.getHeureCreation());
                rechercheCourrierParCle.setLibelleCourrier(repCourrierParCleRechercheDto.getLibelleCourrier());
                rechercheCourrierParCle.setLibelleSituation(repCourrierParCleRechercheDto.getLibelleSituation());
                rechercheCourrierParCle.setNumeroCourrier(repCourrierParCleRechercheDto.getNumeroCourrier());
                rechercheCourrierParCle.setNumeroPli(repCourrierParCleRechercheDto.getNumeroPli());

                rechercheCourrierParCle.setListeCleRecherche(mapArrayOfRepCleRechercheDtoToListICleRecherche().map(
                                repCourrierParCleRechercheDto.getListeCleRecherche(), null));
                rechercheCourrierParCle
                                .setListeFiltreInfoCompDefinition(mapArrayOfRepFiltreInfoCompDefinitionDtoToListIFiltreInfoCompDefinition()
                                                .map(repCourrierParCleRechercheDto.getListeFiltreInfoCompDefinition(),
                                                                null));
                rechercheCourrierParCle
                                .setListeInfoCompCourrier(mapArrayOfRepInfoCompCourrierDtoToListIInfoCompCourrier()
                                                .map(repCourrierParCleRechercheDto.getListeInfoCompCourrier(), null));

                return rechercheCourrierParCle;
            }
        };

        return transformer;
    }

    /**
     * Transform rep cle recherche dto to i cle recherche.
     * 
     * @return the transformer
     */
    private Transformer transformRepCleRechercheDtoToICleRecherche() {

        Transformer transformer = new Transformer() {

            @Override
            public Object transform(Object input) {

                RepCleRechercheDto repCleRechercheDto = RepCleRechercheDto.class.cast(input);

                ICleRecherche cleRecherche = new CleRecherche();

                cleRecherche.setLibelleTypeCle(repCleRechercheDto.getLibelleTypeCle());
                cleRecherche.setNomTypeCle(repCleRechercheDto.getNomTypeCle());
                cleRecherche.setValeurCle(repCleRechercheDto.getValeurCle());

                return cleRecherche;
            }
        };

        return transformer;
    }

    /**
     * Transform rep filtre info comp definition dto to i filtre info comp
     * definition.
     * 
     * @return the transformer
     */
    private Transformer transformRepFiltreInfoCompDefinitionDtoToIFiltreInfoCompDefinition() {

        Transformer transformer = new Transformer() {

            @Override
            public Object transform(Object input) {

                RepFiltreInfoCompDefinitionDto repFiltreInfoCompDefinitionDto =
                                RepFiltreInfoCompDefinitionDto.class.cast(input);

                IFiltreInfoCompDefinition filtreInfoCompDefinition = new FiltreInfoCompDefinition();

                filtreInfoCompDefinition.setLibelleTypeFiltre(repFiltreInfoCompDefinitionDto.getLibelleTypeFiltre());
                filtreInfoCompDefinition.setLibelleValeurDuFiltre(repFiltreInfoCompDefinitionDto
                                .getLibelleValeurDuFiltre());
                filtreInfoCompDefinition.setNomTypeFiltre(repFiltreInfoCompDefinitionDto.getNomTypeFiltre());
                filtreInfoCompDefinition.setValeurDuFiltre(repFiltreInfoCompDefinitionDto.getValeurDuFiltre());

                return filtreInfoCompDefinition;
            }
        };

        return transformer;
    }

    /**
     * Transform rep info comp courrier dto to i info comp courrier.
     * 
     * @return the transformer
     */
    private Transformer transformRepInfoCompCourrierDtoToIInfoCompCourrier() {

        Transformer transformer = new Transformer() {

            @Override
            public Object transform(Object input) {

                RepInfoCompCourrierDto repInfoCompCourrierDto = RepInfoCompCourrierDto.class.cast(input);

                IInfoCompCourrier infoCompCourrier = new InfoCompCourrier();

                infoCompCourrier.setNomTypeInfo(repInfoCompCourrierDto.getNomTypeInfo());
                infoCompCourrier.setValeurInfo(repInfoCompCourrierDto.getValeurInfo());

                return infoCompCourrier;
            }
        };

        return transformer;
    }

}
